/*
    1. 生产者或消费者线程之间必须互斥地操作队列
    2. 生产者和消费者必须有同步
*/

#include <queue>
#include <iostream>
#include <thread>
#include <condition_variable>
#include <mutex>
#include <unistd.h>
#include <vector>

#define MAX_SIZE 10
#define MAX_PRO_SIZE 5
#define MAX_CON_SIZE 10
#define SLEEP_TIME 1

using namespace std;

queue<int> buffer;
mutex mtx;
condition_variable cv;
int p = 0;

void producer()
{
    while (true)
    {
        sleep(SLEEP_TIME);
        unique_lock<mutex> lock(mtx);
        while (buffer.size() > MAX_SIZE)
        {
            cv.wait(lock);
        }
        buffer.emplace(p);
        p++;
        cout << "生产了" << p - 1 << "号产品" << endl;
        cv.notify_one();
    }
}

void consumer()
{
    while (true)
    {
        sleep(SLEEP_TIME);
        unique_lock<mutex> lock(mtx);
        while (buffer.empty())
        {
            cv.wait(lock);
        }

        int produce = buffer.front();
        buffer.pop();
        cout << "消费了" << produce << "号产品" << endl;
        cv.notify_one();
    }
}

int main()
{
    vector<thread> vec;
    for(int i = 0; i < MAX_PRO_SIZE; i++) {
        vec.emplace_back(thread(producer));
    }
    for(int i = 0; i < MAX_CON_SIZE; i++) {
        vec.emplace_back(thread(consumer));
    }
    for(int i = 0; i < MAX_CON_SIZE + MAX_PRO_SIZE; i++) {
        vec[i].join();
    }
}